﻿using NaughtyAttributes;
using UnityEngine;
using UnityEngine.UI;

namespace Gj
{
    public class CanvasSize : MonoBehaviour
    {
        public CanvasScaler scaler;
        public float minValue;
        public float maxValue;
        public float min;
        public float max;
        public NodeSize[] sizeList;
        [SerializeField] private Vector4 full;
        private bool init;
        private string type;

        private void Start()
        {
            Update();
        }

        private void Update()
        {
            if (!init || Screen.width != SystemInput.screenSize.x || Screen.height != SystemInput.screenSize.y || SystemInput.screenOrientation != Screen.orientation)
            {
                Refresh(Screen.orientation);
                Refresh(scaler.referenceResolution.x, scaler.referenceResolution.y, Screen.width, Screen.height);
                init = true;
            }
        }

        [Button]
        public void Refresh()
        {
            var rectTransform = GetComponent<RectTransform>();
            Refresh(scaler.referenceResolution.x, scaler.referenceResolution.y,
                rectTransform.rect.width * rectTransform.localScale.x,
                rectTransform.rect.height * rectTransform.localScale.x);
        }

        private void Refresh(ScreenOrientation o)
        {
            if (SystemInput.screenOrientation == o) return;
            SystemInput.screenOrientation = o;
            if (SystemInput.screenOrientation == ScreenOrientation.Portrait)
            {
#if UNITY_ANDROID && !UNITY_EDITOR
            AndroidScreen.ShowStatusBar();
#endif
            }
            else if (SystemInput.screenOrientation == ScreenOrientation.LandscapeLeft || SystemInput.screenOrientation == ScreenOrientation.LandscapeRight)
            {
#if UNITY_ANDROID && !UNITY_EDITOR
            AndroidScreen.HideStatusBar();
#endif
            }
        }
        

        private void Refresh(float rw, float rh, float w, float h)
        {
            var v = w / h;
            var b = rw / rh;
            var t = v - b;

            t = MathTools.Normalized(minValue, maxValue, t);

            scaler.matchWidthOrHeight = MathTools.linear(min, max, 1 - t);

            var s = GetScale(rw, rh, w, h, scaler.matchWidthOrHeight);

            Refresh(w, h, s);
            for (var i = 0; i < sizeList.Length; i++) sizeList[i].Refresh(rw, rh, w, h, s);
        }

        private float GetScale(float rw, float rh, float w, float h, float math)
        {
            var logWidth = Mathf.Log(w / rw, 2);
            var logHeight = Mathf.Log(h / rh, 2);
            var logWeightedAverage = Mathf.Lerp(logWidth, logHeight, math);
            return Mathf.Pow(2, logWeightedAverage);
        }

        private void Set(Vector4 q)
        {
            SystemInput.screenMax = new Vector2(SystemInput.screenSize.x - q.z * SystemInput.scale,
                SystemInput.screenSize.y - q.w * SystemInput.scale);
            SystemInput.screenMin = new Vector2(q.x, q.y) * SystemInput.scale;
        }

        private void Refresh(float width, float height, float scale)
        {
            SystemInput.scale = scale;
            SystemInput.screenSize = new Vector2(width, height);
            SystemInput.canvasSize = new Vector2(width / scale, height / scale);
            SystemInput.screenCenter = SystemInput.screenSize / 2;
            SystemInput.canvasCenter = SystemInput.canvasSize / 2;
            Set(full);
        }
    }
}